#include "Clerc.h"

//#include <boost/assign/list_of.hpp>

using namespace std;
using namespace boost::assign;

const unsigned int Clerc::nbr_comp = 105;

const unsigned int Clerc::nbr_restric = 18;

/**
 * Les noms des sphères sont accentuées "à la LaTeX", afin de
 * simplifier la gestion des noms de dossiers.
 */
const vector<ListComp> Clerc::Comp = list_of
  (ListComp("Amélioration de la classe d'armure"           , 15))
  (ListComp("Arme symbolique"                              ,  5))
  (ListComp("Bonus au JS contre drain d'énergie"           ,  5))
  (ListComp("Bonus au PV de guerrier"                      , 15))
  (ListComp("Changement de forme"                          ,  0))
  (ListComp("Combat à mains nues"                          , 15))
  (ListComp("Communication"                                , 10))
  (ListComp("Compétences suppémentaires"                   ,  0))
  (ListComp("Connaissance des alignements"                 , 15))
  (ListComp("Contrôle des esprits"                         ,  0))
  (ListComp("Dés de vie à 1d10"                            , 10))
  (ListComp("Détection des morts-vivants"                  , 10))
  (ListComp("Détection du mal"                             , 10))
  (ListComp("Durée de sort accrue (1 sphère)"              , 10))
  (ListComp("Durée de sorts accrue"                        , 15))
  (ListComp("Empathie avec les animaux"                    , 10))
  (ListComp("Guérisseur expert"                            , 10))
  (ListComp("Identification des plantes et animaux (niv 8)",  5))
  (ListComp("Identification des plantes et animaux"        ,  8))
  (ListComp("Immunité à la magie"                          , 15))
  (ListComp("Immunité aux charmes"                         ,  0))
  (ListComp("Immunité aux maladies naturelles"             , 10))
  (ListComp("Imposition des mains"                         , 10))
  (ListComp("Incantation rapide"                           ,  5))
  (ListComp("Inspiration (+1)"                             ,  5))
  (ListComp("Inspiration (+2)"                             , 10))
  (ListComp("Langage secret"                               ,  5))
  (ListComp("Passage sans traces (niv 3)"                  ,  5))
  (ListComp("Passage sans traces"                          ,  7))
  (ListComp("Pouvoir divin"                                ,  0))
  (ListComp("Prêtre combattant"                            , 20))
  (ListComp("Purification de l'eau"                        ,  5))
  (ListComp("Repousser les morts-vivants"                  , 15))
  (ListComp("Résistance au drain d'énergie"                , 15))
  (ListComp("Résistance au feu / électricité"              ,  7))
  (ListComp("Résistance au froid"                          ,  5))
  (ListComp("Sélection d'armes étendues"                   , 10))
  (ListComp("Suivants (niv 8)"                             ,  5))
  (ListComp("Suivants"                                     , 10))
  (ListComp("TAc0 de guerrier"                             , 20))
  (ListComp("Talents de voleur"                            ,  0))
  // compétences -> 41
  (ListComp("G\\'en\\'erale (min)"                         ,  3))
  (ListComp("Animale (min)"                                ,  5))
  (ListComp("Astrale (min)"                                ,  3))
  (ListComp("Chaos (min)"                                  ,  5))
  (ListComp("Charme (min)"                                 ,  5))
  (ListComp("Climat (min)"                                 ,  3))
  (ListComp("Combat (min)"                                 ,  5))
  (ListComp("Conjuration (min)"                            ,  5))
  (ListComp("Cr\\'eation (min)"                            ,  5))
  (ListComp("Divination (min)"                             ,  5))
  (ListComp("El\\'ementaire (min)"                         ,  8))
  (ListComp("Air (min)"                                    ,  2))
  (ListComp("Eau (min)"                                    ,  2))
  (ListComp("Feu (min)"                                    ,  3))
  (ListComp("Terre (min)"                                  ,  3))
  (ListComp("Garde (min)"                                  ,  3))
  (ListComp("Guerre (min)"                                 ,  3))
  (ListComp("Loi (min)"                                    ,  5))
  (ListComp("N\\'ecromancie (min)"                         ,  5))
  (ListComp("Nombres (min)"                                ,  5))
  (ListComp("Pens\\'ee (min)"                              ,  5))
  (ListComp("Protection (min)"                             ,  5))
  (ListComp("Soin (min)"                                   ,  5))
  (ListComp("Soleil (min)"                                 ,  3))
  (ListComp("Temps (min)"                                  ,  5))
  (ListComp("V\\'eg\\'etale (min)"                         ,  5))
  (ListComp("Vigilance (min)"                              ,  5))
  (ListComp("Voyageur (min)"                               ,  3))
  // sphères mineures -> 68
  (ListComp("G\\'en\\'erale (maj)"                         ,  5))
  (ListComp("Animale (maj)"                                , 10))
  (ListComp("Astrale (maj)"                                ,  6))
  (ListComp("Chaos (maj)"                                  ,  8))
  (ListComp("Charme (maj)"                                 , 10))
  (ListComp("Climat (maj)"                                 , 10))
  (ListComp("Combat (maj)"                                 , 10))
  (ListComp("Conjuration (maj)"                            , 10))
  (ListComp("Cr\\'eation (maj)"                            , 10))
  (ListComp("Divination (maj)"                             , 10))
  (ListComp("El\\'ementaire (maj)"                         , 20))
  (ListComp("Air (maj)"                                    ,  5))
  (ListComp("Eau (maj)"                                    ,  5))
  (ListComp("Feu (maj)"                                    ,  8))
  (ListComp("Terre (maj)"                                  ,  8))
  (ListComp("Garde (maj)"                                  ,  5))
  (ListComp("Guerre (maj)"                                 ,  5))
  (ListComp("Loi (maj)"                                    ,  8))
  (ListComp("N\\'ecromancie (maj)"                         , 10))
  (ListComp("Nombres (maj)"                                , 10))
  (ListComp("Pens\\'ee (maj)"                              , 10))
  (ListComp("Protection (maj)"                             , 10))
  (ListComp("Soin (maj)"                                   , 10))
  (ListComp("Soleil (maj)"                                 ,  5))
  (ListComp("Temps (maj)"                                  , 10))
  (ListComp("V\\'eg\\'etale (maj)"                         , 10))
  (ListComp("Vigilance (maj)"                              , 10))
  (ListComp("Voyageur (maj)"                               ,  5))
  (ListComp("Abjuration (mage)"                            , 25))
  (ListComp("Alt\\'eration (mage)"                         , 25))
  (ListComp("Conjuration - Convocation (mage)"             , 25))
  (ListComp("Enchantement - Charme (mage)"                 , 25))
  (ListComp("Divination (mage)"                            , 25))
  (ListComp("Illusion - Fantasme (mage)"                   , 25))
  (ListComp("Invocation - Evocation (mage)"                , 25))
  (ListComp("N\\'ecromancie (mage)"                        , 25));
  // sphères majeures -> 105

const vector<ListComp> Clerc::Restric = list_of
  (ListComp("Cérémonial"                  ,  5))
  (ListComp("Choix des armes restreint"   ,  5))
  (ListComp("Choix de sorts restreint"    ,  5))
  (ListComp("Dés de vie à 1d6"            , 10))
  (ListComp("Dés de vie à 1d4"            , 20))
  (ListComp("Difficultés de mémorisation" ,  5))
  (ListComp("Fanatisme"                   ,  5))
  (ListComp("Incantation longue"          ,  5))
  (ListComp("Limitation à la maille"      ,  5))
  (ListComp("Limitation au cuir clouté"   , 10))
  (ListComp("Limitation d'objets magiques",  0))
  (ListComp("Manque de discrétion"        ,  5))
  (ListComp("Pas d'armes"                 , 15))
  (ListComp("Pas d'armure"                , 15))
  (ListComp("Progression ralentie"        , 15))
  (ListComp("Sorts dangereux"             , 10))
  (ListComp("Tabou"                       ,  2))
  (ListComp("Talisman"                    ,  8));

/** Constructeur usuel.
 * Permet la construction d'un clerc de A à Z, càd on détermine ici
 * les restrictions, puis les compétences.
 * @param xp le nombre de pts d'expérience du Clerc.
 * @param trait les traits du Clerc, le 7ème contient le score de
 * force exceptionnel, fixé à 0 si non applicable.
 * @param PP nombre de points de personnage (PP) à disposition pour la
 * céation du Clerc.
 */
Clerc::Clerc(unsigned int xp, unsigned int trait[7], unsigned int& PP)
  : Classe(xp, trait, Pretres)
{
  Type_classe = "Clerc";
  PP += 120;
  ptrComp = &Comp;
  ptrRes  = &Restric;
  ptrNbrComp = &nbr_comp;
  ptrNbrRes  = &nbr_restric;
  blank() << "********************************************************" << endreq;
  blank() << "Création d'un clerc" << endl << endreq;
  unsigned int nbr(0),  pps(0);

  for (unsigned int i(0); i<nbr_restric; i++)
    {
      if (Restric[i].Cout != 0)
	blank() << i+1 << ' ' << affiche_accent(Restric[i].Comp)
		    << " (" << Restric[i].Cout << " pp)" << endreq;
      else
	blank() << i+1 << ' ' << affiche_accent(Restric[i].Comp)
		    << " cout variable" << endreq;	
    }
  blank() << nbr_restric+1 << " Aucune" << endreq;
  blank() << "Choisir les restrictions" << endreq;

  bool test(true), deja_pris, encore(false);
  unsigned int save_PP(PP);

  do
    {
      do
	{
	  nbr = demander_unsigned_borne("Choisir les restrictions ", 1,
					nbr_restric + 1);
	  
	  if (nbr != nbr_restric+1)
	    {
	      if (Restric[nbr-1].Cout == 0)
		{
		  deja_pris = safe_push_back(&Comp_classe, 104 + nbr);
		  if (deja_pris)
		    warning() << "Déjà sélectionné" << endreq;
		  else
		    {
		      Comp_classe.push_back(104+nbr);
		      pps = demander_unsigned("Entrer les pp obtenus : ");
		      PP += pps;
		      blank() << "Restriction choisie : "
				  << affiche_accent(Restric[nbr-1].Comp) << endreq;
		    }
		}
	      else
		{
		  deja_pris = safe_push_back(&Comp_classe, 104 + nbr);
		  if (deja_pris)
		    warning() << "Déjà sélectionné" << endreq;
		  else
		    {
		      Comp_classe.push_back(104+nbr);
		      PP += Restric[nbr-1].Cout;
		      blank() << "Restriction choisie : "
				  << affiche_accent(Restric[nbr-1].Comp) << endreq;
		    }
		}
	    }
	  else
	    test = false;
	}
      while(test);

      affiche_competences();
      blank() << endl <<  "1 pour continuer, 2 pour recommencer" << endreq;
      nbr = demander_unsigned_borne("Choix ", 1, 2);
      if (nbr == 2)
	{
	  PP = save_PP;
	  Comp_classe.clear();
	  test = true;
	  encore = true;
	  blank() << endreq;
	}
      else
	encore = false;
    }
  while(encore);
      
  blank() << "Tu as " << PP << " pp à dépenser" << endreq;
  save_PP = PP;

  for (unsigned int i(0); i<nbr_comp; i++)
    {
      if (Comp[i].Cout != 0)
	blank() << i+1 << ' ' << affiche_accent(Comp[i].Comp)
		    << " (" << Comp[i].Cout << " pp)" << endreq;
      else
	blank() << i+1 << ' ' << affiche_accent(Comp[i].Comp)
		    << " (cout variable)" << endreq;	
    }
  blank() << nbr_comp+1 << " Aucune" << endreq;
  blank() << "Choisir les compétences de classe" << endreq;

  test = true;

  do
    {
      do
	{
	  nbr = demander_unsigned_borne("("+write_int(PP)+" restants) ", 1,
					nbr_comp + 1);
	  
	  if (nbr!=nbr_comp+1)
	    {
	      deja_pris = safe_push_back(&Comp_classe, nbr - 1);
	      if (deja_pris)
		warning() << "Déjà sélectionné" << endreq;
	      else
		{
		  if (Comp[nbr-1].Cout == 0)
		    {
		      pps = demander_unsigned("Entrez le coût : ");
		    }
		  else
		    pps = Comp[nbr-1].Cout;
		  if (PP >= pps)
		    {
		      Comp_classe.push_back(nbr-1);
		      PP -= Comp[nbr-1].Cout;
		      blank() << "Compétence choisie : " 
				  << affiche_accent(Comp[nbr-1].Comp) << endreq;
		      // tester si c'est les compétences supplémentaires
		      if (nbr == 40)
			TC.push_back(Roublards);
		    }
		  else
		    blank() << "Pas assez de pp" << endreq;
		}
	    }
	  else
	    test = false;
	}
      while(test);

      affiche_competences();
      blank() << endl <<  "1 pour continuer, 2 pour recommencer" << endreq;
      nbr = demander_unsigned_borne("Choix ", 1, 2);
      if (nbr == 2)
	{
	  PP = save_PP;
	  while(Comp_classe.back() < nbr_comp)
	    Comp_classe.pop_back();
	  test = true;
	  encore = true;
	  blank() << endreq;
	}
      else
	encore = false;
    }
  while(encore);

  blank() << endl << setfill('*') << setw(56) << '*' << setfill(' ')
	      << endreq;
  calcul_niveau();
  calcul_niv_mag();
}

/** Constructeur simplifié.
 * Permet de construire un Clerc lors de la lecture d'un ficier xml.
 * @param xp le nombre de pts d'expérience du Clerc.
 * @param trait les traits du Clerc, le 7ème contient le score de
 * force exceptionnel, fixé à 0 si non applicable.
 */
Clerc::Clerc(unsigned int xp, unsigned int trait[7])
  : Classe(xp, trait, Pretres)
{
  Type_classe = "Clerc";
  ptrComp = &Comp;
  ptrRes  = &Restric;
  ptrNbrComp = &nbr_comp;
  ptrNbrRes  = &nbr_restric;
  calcul_niveau();
  calcul_niv_mag();
}

Clerc::Clerc(unsigned int xp, unsigned int trait[7], const bool& UI)
  : Classe(xp, trait, Pretres)
{
  Type_classe = "Clerc";
  ptrComp = &Comp;
  ptrRes  = &Restric;
  ptrNbrComp = &nbr_comp;
  ptrNbrRes  = &nbr_restric;
  
  if (!UI)
    {
      error() << "Création du personnage impossible" << endreq;
      exit(1);
    }

  calcul_niveau();
  calcul_niv_mag();
}

Clerc::~Clerc()
{}

void Clerc::calcul_niveau()
{
  if (XP < 13000)
    {
      unsigned int i;
      for (i = 0; i < 3; i++)
	{
	  if (XP < (unsigned int) 1500 * puissance(2, i))
	    break;
	}
      Niveau = i + 1;
    }
  else if (XP < 27500)
    Niveau = 5;
  else if (XP < 55000)
    Niveau = 6;
  else if (XP < 110000)
    Niveau = 7;
  else if (XP < 225000)
    Niveau = 8;
  else
      Niveau = (XP - 225000) / 225000 + 9;
}

// /**
//  * Il faut faire attention aux accents...
//  * @see affiche_accent
//  */
// void Clerc::afficher_stats(ostream& os)
// {
//   os << "Classe : Clerc" << endreq;
//   for (unsigned int i(0); i<6; i++)
//     os << Caracteristiques[i] << ' ' << Traits[i] << endreq;
//   for (unsigned int i(0); i<Comp_classe.size(); i++)
//     {
//       if (Comp_classe[i] >= nbr_comp)
// 	os << affiche_accent(Restric[Comp_classe[i]-nbr_comp].Comp)
// 		    << endreq;
//       else
// 	os << affiche_accent(Comp[Comp_classe[i]].Comp) << endreq;
//     }
// }

void Clerc::appliquer_modif(const string& type)
{}

void Clerc::augmenter_talents(const unsigned int& bonus, const bool& lvl_up)
{}

void Clerc::get_JS(unsigned int *tab) const
{
  DebugLevelType etat_precedent(dout.getLevel());
  dout.setLevel(fonction);
  *(tab + 0) = 10; // Paralysie, Poison ou Mort magique
  *(tab + 1) = 14; // Bâton, batonnet baguette
  *(tab + 2) = 13; // Pétrification ou Métamorphose
  *(tab + 3) = 16; // Souffles
  *(tab + 4) = 15; // Sorts

  debug() << "Niveau = " << Niveau << endreq;
  
  unsigned int cat;
  if (Niveau <= 3)
    cat = 0;
  else if (Niveau <= 6)
    cat = 1;
  else if (Niveau <= 9)
    cat = 3;
  else if (Niveau <= 12)
    cat = 4;
  else if (Niveau <= 15)
    cat = 5;
  else if (Niveau <= 18)
    cat = 6;
  else
    cat = 8;

  *(tab + 0) -= cat;
  *(tab + 1) -= cat;
  *(tab + 2) -= cat;
  *(tab + 3) -= cat;
  *(tab + 4) -= cat;
  dout.setLevel(etat_precedent);
}

/**
 * Si Classe::elementaire a la valeur DEBUG, la distinction Compétence /
 * Restriction est affichée.
 */
string Clerc::get_competence(const unsigned int& i) const
{
  DebugLevelType etat_precedent(dout.getLevel());
  dout.setLevel(elementaire);
  if (get_comp(i) < nbr_comp)
    {
      debug() << "comp " << get_comp(i) << " => comp" << endreq;
      dout.setLevel(etat_precedent);
      return Comp[get_comp(i)].Comp;
    }
  else
    {
      debug() << "comp " << get_comp(i) << " => res" << endreq;
      dout.setLevel(etat_precedent);
      return Restric[get_comp(i)-nbr_comp].Comp;
    }
}

unsigned int Clerc::calcule_TAc0() const
{
  unsigned int mod_niveau(2 * ((Niveau - 1) / 3));

  return 20 - mod_niveau;
}

void Clerc::calcul_niv_mag()
{
  if (Niveau < 16)
    Niveau_mag = (Niveau + 1) / 2;
  else
    Niveau_mag = 7;
}

/**
 * Les sorts disponibles pour un Clerc sont donnés par son niveau et
 * les sphères auquelles il a accès.
 *
 * La variable Classe::fonction permet d'afficher :
 *
 * FUNC  : le nom du fichier qui va être écrit
 *
 * LINFO : la vérification que la compétence est bien une sphère, ou une
 * école de magie
 *
 * LFUNC : gestion des sphères élémentaires et des accents
 *
 * DEBUG : ouverture du fichier, 
 * 
 */
void Clerc::ecrire_sorts(const string& nom_fichier, const bool& ecrase) const
{
  DebugLevelType etat_precedent(dout.getLevel());
  dout.setLevel(fonction);
  func() << "Clerc::ecrire_sorts -> début" << endreq;
  ofstream sortie;
  string nom_complet, tmp;
  func() << "A écrire : " << nom_fichier << endreq;

  if (ecrase)
    /*
     * Ecrase l'éventuel contenu du fichier
     */
    {
      sortie.open(nom_fichier.c_str());
      debug() << "Ouverture                [ OK ]" << endreq;
    }
  else
    /*
     * Alors on ouvre le fichier de telle sorte à écrire à la suite
     */
    {
      sortie.open(nom_fichier.c_str(), ios::app);
      debug() << "Ouverture                [ OK ]" << endreq;
    }

  sortie << "\\section*{Sorts disponibles - Prêtre}" << endl;

  unsigned int *vec = new unsigned int[Niveau_mag];

  nbr_sort(vec, Niveau_mag);

  sortie << "\\begin{center}" << endl 
	 << "\\begin{tabular*}{10cm}{@{\\extracolsep{\\fill}} l r}"
	 << endl << "\\multicolumn{2}{c}{Nombre de sorts par jour} \\\\"
	 << "\\hline \\\\ \\vspace{1mm}" << endl;
  for (unsigned int i(0); i < Niveau_mag; i++)
    sortie << "Niveau " << i+1 << " & " << *(vec + i) << " \\\\" << endl;
  sortie << "\\end{tabular*}" << endl << "\\end{center}" << endl;

  unsigned int taille(get_combien());
  size_t loc;

  for (unsigned int i(0); i < taille; i++)
    {
      if (get_comp(i) > 2)
	{
	  tmp = get_competence(i);
	  linfo() << "Check sphère : " << tmp << endreq;
	  loc = tmp.find(" (m", 0);
	  if (loc == string::npos)
	    {
	      lfunc() << "Pas une sphère..." << endreq;
	      continue;
	    }
	  tmp.replace(loc, 6, "");
	  loc = tmp.find("mentaire", 0);
	  if (loc != string::npos)
	    {
	      lfunc() << "Sphère Elémentaire..." << endreq;
	      continue;
	    }
	  
	  loc = tmp.find(")", 0);
	  if (loc != string::npos)
	    {
	      linfo() << "Ecole de magie" << endreq;
	      tmp = supprime_accents(tmp);
	      loc = tmp.find(")", 0);
	      if (loc != string::npos)
		  tmp.replace(loc, 1, "");
	      tmp += "_mage";
	    }

	  for (unsigned int j(1); j <= Niveau_mag; j++)
	    {
	      if (get_comp(i) < 68 && j > 3)
		/*
		 * Accès mineur => jusqu'au lvl 3 uniquement!
		 */
		break;
	      lfunc() << "accents loin " << supprime_accents(tmp) << endreq;
	      sortie << "\\input{../../Sorts-clerc/" << supprime_accents(tmp)
		     << "-"  << write_int(j) << ".inc.tex}" << endl;
	      
	    }
	
	}
    }
  //delete vec;
  sortie.close();
  func() << "Clerc::ecrire_sorts -> fin" << endreq;
  dout.setLevel(etat_precedent);
}

void Clerc::nbr_sort(unsigned int sorts[], const unsigned int& taille) const
{
  DebugLevelType etat_precedent(dout.getLevel());
  dout.setLevel(fonction);
  unsigned int i;
  unsigned int tmp[7];
  func() << "Taille = " << taille << endreq;

  for (i = 0; i < taille; i++)
    tmp[i] = 0;

  switch(Niveau)
    {
    case 1:
      tmp[0] = 1;
      break;
    case 2:
      tmp[0] = 2;
      break;
    case 3:
      tmp[0] = 2;
      tmp[1] = 1;
      break;
    case 4:
      tmp[0] = 3;
      tmp[1] = 2;
      break;
    case 5:
      tmp[0] = 3;
      tmp[1] = 3;
      tmp[2] = 1;
      break;
    case 6:
      tmp[0] = 3;
      tmp[1] = 3;
      tmp[2] = 2;
      break;
    case 7:
      tmp[0] = 3;
      tmp[1] = 3;
      tmp[2] = 2;
      tmp[3] = 1;
      break;
    case 8:
      tmp[0] = 3;
      tmp[1] = 3;
      tmp[2] = 3;
      tmp[3] = 2;
      break;
    case 9:
      tmp[0] = 4;
      tmp[1] = 4;
      tmp[2] = 3;
      tmp[3] = 2;
      tmp[4] = 1;
      break;
    case 10:
      tmp[0] = 4;
      tmp[1] = 4;
      tmp[2] = 3;
      tmp[3] = 3;
      tmp[4] = 2;
      break;
    case 11:
      tmp[0] = 5;
      tmp[1] = 4;
      tmp[2] = 4;
      tmp[3] = 3;
      tmp[4] = 2;
      if (Traits[4] >= 17)
      tmp[5] = 1;
      break;
    case 12:
      tmp[0] = 6;
      tmp[1] = 5;
      tmp[2] = 5;
      tmp[3] = 3;
      tmp[4] = 2;
      if (Traits[4] >= 17)
      tmp[5] = 2;
      break;
    case 13:
      tmp[0] = 6;
      tmp[1] = 6;
      tmp[2] = 6;
      tmp[3] = 4;
      tmp[4] = 2;
      if (Traits[4] >= 17)
      tmp[5] = 2;
      break;
    case 14:
      tmp[0] = 6;
      tmp[1] = 6;
      tmp[2] = 6;
      tmp[3] = 5;
      tmp[4] = 3;
      if (Traits[4] >= 17)
      tmp[5] = 2;
      if (Traits[4] >= 18)
      tmp[6] = 1;
      break;
    case 15:
      tmp[0] = 6;
      tmp[1] = 6;
      tmp[2] = 6;
      tmp[3] = 6;
      tmp[4] = 4;
      if (Traits[4] >= 17)
	tmp[5] = 2;
      if (Traits[4] >= 18)
	tmp[6] = 1;
      break;
    case 16:
      tmp[0] = 7;
      tmp[1] = 7;
      tmp[2] = 7;
      tmp[3] = 6;
      tmp[4] = 4;
      if (Traits[4] >= 17)
	tmp[5] = 3;
      if (Traits[4] >= 18)
	tmp[6] = 1;
      break;
    case 17:
      tmp[0] = 7;
      tmp[1] = 7;
      tmp[2] = 7;
      tmp[3] = 7;
      tmp[4] = 5;
      if (Traits[4] >= 17)
	tmp[5] = 3;
      if (Traits[4] >= 18)
	tmp[6] = 2;
      break;
    case 18:
      tmp[0] = 8;
      tmp[1] = 8;
      tmp[2] = 8;
      tmp[3] = 8;
      tmp[4] = 6;
      if (Traits[4] >= 17)
	tmp[5] = 4;
      if (Traits[4] >= 18)
	tmp[6] = 2;
      break;
    case 19:
      tmp[0] = 9;
      tmp[1] = 9;
      tmp[2] = 8;
      tmp[3] = 8;
      tmp[4] = 6;
      if (Traits[4] >= 17)
	tmp[5] = 4;
      if (Traits[4] >= 18)
	tmp[6] = 2;
      break;
    default:
      tmp[0] = 9;
      tmp[1] = 9;
      tmp[2] = 9;
      tmp[3] = 8;
      tmp[4] = 7;
      if (Traits[4] >= 17)
	tmp[5] = 5;
      if (Traits[4] >= 18)
	tmp[6] = 2;
      break;
    }

  for (i = 0; i < Niveau_mag; i++)
    sorts[i] = tmp[i];

  unsigned int compteur1(0), compteur2(0), compteur3(0), compteur4(0);

  if (Traits[4] >= 13 && Traits[4] < 18)
    {
      compteur1 = (Traits[4] - 11) / 2;
      compteur2 = (Traits[4] - 12) / 2;
    }
  else if (Traits[4] >= 18 && Traits[4] < 19)
    {
      compteur1 = Traits[4] - 14;
      compteur2 = Traits[4] - 16;
    }
  else if (Traits[4] >= 19 && Traits[4] < 23)
    {
      compteur1 = (Traits[4] + 1) / 2 - 6;
      compteur2 = Traits[4] / 2 - 6;
      compteur3 = Traits[4] - 18;
    }
  else
    {
      compteur1 = (Traits[4] + 1) / 2 - 6;
      compteur2 = Traits[4] / 2 - 6;
      compteur3 = Traits[4] - 19;
      compteur4 = 1;
    }

  for (i = 0; i < compteur1; i++)
    {
      if (i == Niveau_mag)
	break;
      sorts[i]++;
    }
  for (i = 0; i < compteur2; i++)
    {
      if (i == Niveau_mag)
	break;
      sorts[i]++;
    }
  for (i = 0; i < compteur3; i++)
    {
      if (i == Niveau_mag)
	break;
      sorts[i]++;
    }
  for (i = 0; i < compteur4; i++)
    {
      if (i == Niveau_mag)
	break;
      sorts[i]++;
    }

  dout.setLevel(etat_precedent);  
}

/**
 * Permet de gérer les compétences martiales, càd lesquelles sont accessibles
 * à quel coût.
 *
 * Un Clerc peut prendre un arme réservée au Clerc pour 3 pp, ou alors une
 * arme de Guerrier pour 4 pp.
 */
void Clerc::get_prix_acces(map<string, unsigned int>* Map) const
{
  DebugLevelType etat_precedent(dout.getLevel());
  dout.setLevel(fonction);
  func() << "Clerc::get_prix_acces -> début" << endreq;

  map<string, unsigned int>::const_iterator mapIt, mapBegin(Map -> begin()),
    mapEnd(Map -> end());

  for (mapIt = mapBegin; mapIt != mapEnd; mapIt++)
       lfunc() << mapIt -> first << endreq;
 
  mapIt = Map -> find("Clerc");
  if ((mapIt != mapEnd && mapIt -> second > 3) || mapIt == mapEnd)
    Map -> operator[]("Clerc")    = 3;
  mapIt = Map -> find("Guerrier");
  if ((mapIt != mapEnd && mapIt -> second > 4) || mapIt == mapEnd)
    Map -> operator[]("Guerrier") = 4;
  
  func() << "Clerc::ajout_sorts -> fin" << endreq;
  dout.setLevel(etat_precedent);
}
